/***********************************************************
*                                                          *
*  Check if the cIOS used is a d2x/Waninkoko/Hermes cIOS   *
*                                                          *
* Source code from USB LOADER GX .Modifications by xFede   *
*                                                          *
***********************************************************/

#include <gctypes.h>

#include "ios_check.h"
#include "tools.h"

#define ALIGN32(x) (((x) + 31) & ~31)


/*
 * Check if the cIOS used is a Hermes cIOS.
 */
bool IsHermes(s32 ios)
{
        return (ios == 202 || ios == 222 || ios == 223 || ios == 224 || ios == 225);
}

/*
 * Check if the cIOS passed is a Waninkoko cIOS.
 */
bool IsWaninkoko(s32 ios)
{
        if(ios < 200 || ios > 255)
                return false;

        return !IsHermes(ios);
}

/*
 * Check if the cIOS used is a d2x cIOS.
 */
bool IsD2X(s32 ios)
{
        iosinfo_t *info = GetIOSInfo(ios);
        if(!info)
                return false;

        bool res = (strncasecmp(info->name, "d2x", 3) == 0);

        return res;
}

/*
 * Reads the ios info struct from the .app file.
 * @return pointer to iosinfo_t on success else NULL. The user is responsible for freeing the buffer.
 */
iosinfo_t *GetIOSInfo(s32 ios)
{
        int currentIOS = -1;
        iosinfo_t *currentIOSInfo = NULL;

        if(currentIOS == ios && currentIOSInfo)
                return currentIOSInfo;

        if(currentIOSInfo)
        {
                free(currentIOSInfo);
                currentIOSInfo = NULL;
        }

        currentIOS = ios;
        char filepath[ISFS_MAXPATH] ATTRIBUTE_ALIGN(32);
        u64 TicketID = ((((u64) 1) << 32) | ios);
        u32 TMD_Length;

        s32 ret = ES_GetStoredTMDSize(TicketID, &TMD_Length);
        if (ret < 0)
                return NULL;

        signed_blob *TMD = (signed_blob*) memalign(32, ALIGN32(TMD_Length));
        if (!TMD)
                return NULL;

        ret = ES_GetStoredTMD(TicketID, TMD, TMD_Length);
        if (ret < 0)
        {
                free(TMD);
                return NULL;
        }

        sprintf(filepath, "/title/%08x/%08x/content/%08x.app", 0x00000001, ios, *(u8 *)((u32)TMD+0x1E7));

        free(TMD);

        u8 *buffer = NULL;
        u32 filesize = 0;

        load_file_from_nand(filepath, &buffer, &filesize);
		

        if(!buffer)
                return NULL;

        iosinfo_t *iosinfo = (iosinfo_t *) buffer;

        if(iosinfo->magicword != 0x1ee7c105 || iosinfo->magicversion != 1)
        {
                free(buffer);
                return NULL;
        }

        iosinfo = (iosinfo_t *) realloc(buffer, sizeof(iosinfo_t));
        if(!iosinfo)
                iosinfo = (iosinfo_t *) buffer;

        currentIOSInfo = iosinfo;

        return iosinfo;
}
